{
  // 泛型   泛是广泛的意思
  /**
   * 声明一个函数, 用来返回一个数组, 数组中包含 n 个 value 的值
   */
  function createArray(value: any, n: number): any[] {
    //声明一个空数组
    let arr: any[] = [];
    //循环
    for (let i = 0; i < n; i++) {
      arr.push(value);
    }
    //返回数组
    return arr;
  }

  //调用函数
  let result = createArray("abc", 10);

  // result[0].toFixed(2);//这里有错误, 但是不提醒, 因为 TS 不知道元素的类型
}

{
  interface Computer {
    brand: string;
    price: number;
  }

  //引入泛型  常用的类型(泛型)参数有 T, P, V, K, R
  function createArray<T>(value: T, n: number): T[] {
    //声明一个空数组
    let arr: T[] = [];
    //循环
    for (let i = 0; i < n; i++) {
      arr.push(value);
    }
    //返回数组
    return arr;
  }

  //调用函数
  // let result = createArray<string>('love', 10);
  // result[0].length  //这里有提示
  // result[0].toFixed(2);//这里有报错

  //二次调用
  let result = createArray<Computer>({ brand: "xxx", price: 2000 }, 10);
  // result[0].brand//这里也有提示
}

{
  function createArray<T, K>(a: T, b: K): [T, K] {
    return [a, b];
  }

  //调用函数
  // let result = createArray<string, number>('张三', 18);
  //类型推断
  let result = createArray("周杰伦", 36);
  console.log(result[0].length);

  // result[0].length //这里有提示
  // console.log(result[1].toFixed(2));
}

{
  interface Response<T> {
    status: number;
    headers: object;
    data: T;
  }

  interface Book {
    id: number;
    name: string;
    price: number;
  }

  interface Movie {
    id: number;
    title: string;
    time: number;
  }

  //声明一个对象
  let response: Response<Book> = {
    status: 200,
    headers: {
      contentType: "text/html;charset=utf-8",
    },
    data: {
      id: 1,
      name: "三体",
      price: 29,
    },
  };

  let response2: Response<Movie> = {
    status: 200,
    headers: {},
    data: {
      id: 2,
      title: "西虹市首富",
      time: 2015,
    },
  };

  console.log(response.data.price);
  console.log(response2.data.title);
}

{
  //定义一个接口
  interface Response<T>{
    status: number;
    headers: object;
    data: T
  }

  interface ResponseBody<T>{
    code: string;
    msg: string;
    data: T
  }

  interface Book {
    id: number;
    name: string;
    price: number;
  }

  interface Movie {
    id: number;
    title: string;
    time: number;
  }
  

  let response: Response<ResponseBody<Book>> = {
    status: 200,
    headers: {
      contentType: "text/html;charset=utf-8",
    },
    data: {
      code: "0000",
      msg: "操作成功",
      data: {
        id: 1,
        name: "三体",
        price: 29,
      },
    },
  };

  let response2:Response<ResponseBody<Movie>> = {
    status: 200,
    headers: {
      contentType: "text/html;charset=utf-8",
    },
    data: {
      code: "0000",
      msg: "操作成功",
      data: {
        id: 2,
        title: '夏洛特烦恼',
        time: 2015
      },
    },
  };
}

{
  // 泛型类
  class Container<T>{
    //成员属性的初始化
    store: T[] = [];

    //添加一个方法
    add(arg: T){
      this.store.push(arg);
      return this.store.length;
    }
    //返回所有
    getAll():T[]{
      return this.store;
    }
  }
  //实例化
  let c = new Container<string>();
  //新增
  c.add('123');
  //调用 getAll
  let result = c.getAll();
  
  // result[0].length //这里有提示

}


{ 
  interface LengthRequired{
    length: number;
  }

  //声明一个函数, 获得数据的长度  泛型约束
  function getLength<T extends LengthRequired>(arg: T){
    return arg.length;
  }

  // getLength(undefined);//这里有报错
  getLength('abc');
  getLength([]);
  // getLength(null);//这里有报错
}